package com.greyshark.lib.bluetooth

import com.greyshark.lib.bluetooth.entity.query.LightingInfoEntity
import com.greyshark.lib.bluetooth.extensions.toByteArrayReverse
import com.greyshark.lib.bluetooth.extensions.toFixByteArrayReverse
import com.greyshark.lib.bluetooth.extensions.toLittleEndian
import com.greyshark.lib.bluetooth.utils.ModbusCrc16Utils
import java.io.ByteArrayOutputStream

class ProtocolCommand {

  companion object {

    @JvmStatic
    private val stream = ByteArrayOutputStream()

    //region query
    //查询设备信息命令（ 命令类型 = 0×0101）
    @JvmStatic
    fun queryDeviceInfo(): ByteArray {
      val packetData =
        0x0101L.toLittleEndian(2) +
                0x0001L.toLittleEndian(2) +
                0x0001L.toLittleEndian(2) +
                0x0000L.toLittleEndian(2)
      stream.write(0x5689L.toLittleEndian(2))
      stream.write(packetData)
      stream.write(ModbusCrc16Utils.calculateModbusCRC16(packetData))
      stream.write(0x3AB5L.toLittleEndian(2))
      val packet = stream.toByteArray().copyOf()
      stream.reset()
      return packet
    }

    //查询电量信息命令（ 命令类型 = 0×0102）
    @JvmStatic
    fun queryDeviceBattery(): ByteArray {
      val packetData =
        0x0102L.toLittleEndian(2) +
                0x0001L.toLittleEndian(2) +
                0x0001L.toLittleEndian(2) +
                0x0000L.toLittleEndian(2)
      stream.write(0x5689L.toLittleEndian(2))
      stream.write(packetData)
      stream.write(ModbusCrc16Utils.calculateModbusCRC16(packetData))
      stream.write(0x3AB5L.toLittleEndian(2))
      val packet = stream.toByteArray().copyOf()
      stream.reset()
      return packet
    }

    //查询⽤户信息命令（ 命令类型 = 0×0103）
    @JvmStatic
    fun queryUserInfo(): ByteArray {
      val packetData =
        0x0103L.toLittleEndian(2) +
                0x0001L.toLittleEndian(2) +
                0x0001L.toLittleEndian(2) +
                0x0000L.toLittleEndian(2)
      stream.write(0x5689L.toLittleEndian(2))
      stream.write(packetData)
      stream.write(ModbusCrc16Utils.calculateModbusCRC16(packetData))
      stream.write(0x3AB5L.toLittleEndian(2))
      val packet = stream.toByteArray().copyOf()
      stream.reset()
      return packet
    }

    //查询健康信息命令（ 命令类型 = 0×0104）5分钟记录⼀次
    @JvmStatic
    fun queryHealthInfo(time: Long): ByteArray {
      val packetData =
        0x0104L.toLittleEndian(2) +
                0x0001L.toLittleEndian(2) +
                0x0001L.toLittleEndian(2) +
                0x0006L.toLittleEndian(2) +
                time.toLittleEndian(6)
      stream.write(0x5689L.toLittleEndian(2))
      stream.write(packetData)
      stream.write(ModbusCrc16Utils.calculateModbusCRC16(packetData))
      stream.write(0x3AB5L.toLittleEndian(2))
      val packet = stream.toByteArray().copyOf()
      stream.reset()
      return packet
    }

    //查询睡眠信息命令（ 命令类型 = 0×0105）
    @JvmStatic
    fun queryNightTimeSleepInfo(time: Long): ByteArray {
      val packetData =
        0x0105L.toLittleEndian(2) +
                0x0001L.toLittleEndian(2) +
                0x0001L.toLittleEndian(2) +
                0x0006L.toLittleEndian(2) +
                time.toLittleEndian(6)
      stream.write(0x5689L.toLittleEndian(2))
      stream.write(packetData)
      stream.write(ModbusCrc16Utils.calculateModbusCRC16(packetData))
      stream.write(0x3AB5L.toLittleEndian(2))
      val packet = stream.toByteArray().copyOf()
      stream.reset()
      return packet
    }

    //查询⼩睡信息命令（ 命令类型 = 0×0106）
    @JvmStatic
    fun queryDayTimeSleepInfo(time: Long): ByteArray {
      val packetData =
        0x0106L.toLittleEndian(2) +
                0x0001L.toLittleEndian(2) +
                0x0001L.toLittleEndian(2) +
                0x0006L.toLittleEndian(2) +
                time.toLittleEndian(6)
      stream.write(0x5689L.toLittleEndian(2))
      stream.write(packetData)
      stream.write(ModbusCrc16Utils.calculateModbusCRC16(packetData))
      stream.write(0x3AB5L.toLittleEndian(2))
      val packet = stream.toByteArray().copyOf()
      stream.reset()
      return packet
    }

    //查询运动信息命令（ 命令类型 = 0×0107）（可能多段）
    @JvmStatic
    fun querySportRecordInfo(time: Long): ByteArray {
      val packetData =
        0x0107L.toLittleEndian(2) +
                0x0001L.toLittleEndian(2) +
                0x0001L.toLittleEndian(2) +
                0x0006L.toLittleEndian(2) +
                time.toLittleEndian(6)
      stream.write(0x5689L.toLittleEndian(2))
      stream.write(packetData)
      stream.write(ModbusCrc16Utils.calculateModbusCRC16(packetData))
      stream.write(0x3AB5L.toLittleEndian(2))
      val packet = stream.toByteArray().copyOf()
      stream.reset()
      return packet
    }

    //查询实时运动信息命令（ 命令类型 = 0×0108）
    @JvmStatic
    fun queryRealTimeSportInfo(isOpen: Boolean): ByteArray {
      val packetData =
        0x0108L.toLittleEndian(2) +
                0x0001L.toLittleEndian(2) +
                0x0001L.toLittleEndian(2) +
                0x0001L.toLittleEndian(2) +
                (if (isOpen) 0x01 else 0x02)
      stream.write(0x5689L.toLittleEndian(2))
      stream.write(packetData)
      stream.write(ModbusCrc16Utils.calculateModbusCRC16(packetData))
      stream.write(0x3AB5L.toLittleEndian(2))
      val packet = stream.toByteArray().copyOf()
      stream.reset()
      return packet
    }

    //查询站⽴信息命令（ 命令类型 = 0×0109）
    @JvmStatic
    fun queryEffectStandInfo(time: Long): ByteArray {
      val packetData =
        0x0109L.toLittleEndian(2) +
                0x0001L.toLittleEndian(2) +
                0x0001L.toLittleEndian(2) +
                0x0006L.toLittleEndian(2) +
                time.toLittleEndian(6)
      stream.write(0x5689L.toLittleEndian(2))
      stream.write(packetData)
      stream.write(ModbusCrc16Utils.calculateModbusCRC16(packetData))
      stream.write(0x3AB5L.toLittleEndian(2))
      val packet = stream.toByteArray().copyOf()
      stream.reset()
      return packet
    }

    //查询实时⼼率（ 命令类型 = 0×01A0）
    @JvmStatic
    fun queryHeartRateInfo(isOpen: Boolean): ByteArray {
      val packetData =
        0x01A0L.toLittleEndian(2) +
                0x0001L.toLittleEndian(2) +
                0x0001L.toLittleEndian(2) +
                0x0002L.toLittleEndian(2) +
                0x01 + (if (isOpen) 0x01 else 0x02)
      stream.write(0x5689L.toLittleEndian(2))
      stream.write(packetData)
      stream.write(ModbusCrc16Utils.calculateModbusCRC16(packetData))
      stream.write(0x3AB5L.toLittleEndian(2))
      val packet = stream.toByteArray().copyOf()
      stream.reset()
      return packet
    }

    //查询实时血氧（ 命令类型 = 0×01A0）
    @JvmStatic
    fun queryBloodOxygenInfo(isOpen: Boolean): ByteArray {
      val packetData =
        0x01A0L.toLittleEndian(2) +
                0x0001L.toLittleEndian(2) +
                0x0001L.toLittleEndian(2) +
                0x0002L.toLittleEndian(2) +
                0x02 + (if (isOpen) 0x01 else 0x02)
      stream.write(0x5689L.toLittleEndian(2))
      stream.write(packetData)
      stream.write(ModbusCrc16Utils.calculateModbusCRC16(packetData))
      stream.write(0x3AB5L.toLittleEndian(2))
      val packet = stream.toByteArray().copyOf()
      stream.reset()
      return packet
    }

    //查询实时体温（ 命令类型 = 0×01A0）
    @JvmStatic
    fun queryTemperatureInfo(isOpen: Boolean): ByteArray {
      val packetData =
        0x01A0L.toLittleEndian(2) +
                0x0001L.toLittleEndian(2) +
                0x0001L.toLittleEndian(2) +
                0x0002L.toLittleEndian(2) +
                0x03 + (if (isOpen) 0x01 else 0x02)
      stream.write(0x5689L.toLittleEndian(2))
      stream.write(packetData)
      stream.write(ModbusCrc16Utils.calculateModbusCRC16(packetData))
      stream.write(0x3AB5L.toLittleEndian(2))
      val packet = stream.toByteArray().copyOf()
      stream.reset()
      return packet
    }

    //查询⽀持功能命令（ 命令类型 = 0×01A1）
    @JvmStatic
    fun querySupportFunction(): ByteArray {
      val packetData =
        0x01A1L.toLittleEndian(2) +
                0x0001L.toLittleEndian(2) +
                0x0001L.toLittleEndian(2) +
                0x0000
      stream.write(0x5689L.toLittleEndian(2))
      stream.write(packetData)
      stream.write(ModbusCrc16Utils.calculateModbusCRC16(packetData))
      stream.write(0x3AB5L.toLittleEndian(2))
      val packet = stream.toByteArray().copyOf()
      stream.reset()
      return packet
    }

    //⽇常数据命令（ 命令类型 = 0×01A2）
    @JvmStatic
    fun queryDailyInfo(time: Long): ByteArray {
      val packetData =
        0x01A2L.toLittleEndian(2) +
                0x0001L.toLittleEndian(2) +
                0x0001L.toLittleEndian(2) +
                0x0006L.toLittleEndian(2) +
                time.toLittleEndian(6)
      stream.write(0x5689L.toLittleEndian(2))
      stream.write(packetData)
      stream.write(ModbusCrc16Utils.calculateModbusCRC16(packetData))
      stream.write(0x3AB5L.toLittleEndian(2))
      val packet = stream.toByteArray().copyOf()
      stream.reset()
      return packet
    }


    //查询⽬前灯效设置结果命令（ 命令类型 = 0×01A4）
    @JvmStatic
    fun queryLightingSettings(): ByteArray {
      val packetData =
        0x01A4L.toLittleEndian(2) +
                0x0001L.toLittleEndian(2) +
                0x0001L.toLittleEndian(2) +
                0x00 + 0x00
      stream.write(0x5689L.toLittleEndian(2))
      stream.write(packetData)
      stream.write(ModbusCrc16Utils.calculateModbusCRC16(packetData))
      stream.write(0x3AB5L.toLittleEndian(2))
      val packet = stream.toByteArray().copyOf()
      stream.reset()
      return packet
    }


    //查询⽬前灯效免打扰设置结果命令（ 命令类型 = 0×01A5）
    @JvmStatic
    fun queryLightingNotDisturbInfo(): ByteArray {
      val packetData =
        0x01A5L.toLittleEndian(2) +
                0x0001L.toLittleEndian(2) +
                0x0001L.toLittleEndian(2) +
                0x00 + 0x00
      stream.write(0x5689L.toLittleEndian(2))
      stream.write(packetData)
      stream.write(ModbusCrc16Utils.calculateModbusCRC16(packetData))
      stream.write(0x3AB5L.toLittleEndian(2))
      val packet = stream.toByteArray().copyOf()
      stream.reset()
      return packet
    }

    //查询mtu值命令（ 命令类型 = 0×01A3）
    @JvmStatic
    fun queryMTU(): ByteArray {
      val packetData =
        0x01A3L.toLittleEndian(2) +
                0x0001L.toLittleEndian(2) +
                0x0001L.toLittleEndian(2) +
                0x00 + 0x00
      stream.write(0x5689L.toLittleEndian(2))
      stream.write(packetData)
      stream.write(ModbusCrc16Utils.calculateModbusCRC16(packetData))
      stream.write(0x3AB5L.toLittleEndian(2))
      val packet = stream.toByteArray().copyOf()
      stream.reset()
      return packet
    }
    //endregion query

    //region push
    //同步时间命令（ 命令类型 = 0×0201）
    @JvmStatic
    fun pushTimeInfo(time: Long, timeZone: Int): ByteArray {
      val packetData =
        0x0201L.toLittleEndian(2) +
                0x0001L.toLittleEndian(2) +
                0x0001L.toLittleEndian(2) +
                0x0007L.toLittleEndian(2) +
                time.toLittleEndian(6) +
                timeZone.toByte()
      stream.write(0x5689L.toLittleEndian(2))
      stream.write(packetData)
      stream.write(ModbusCrc16Utils.calculateModbusCRC16(packetData))
      stream.write(0x3AB5L.toLittleEndian(2))
      val packet = stream.toByteArray().copyOf()
      stream.reset()
      return packet
    }

    //同步灯光控制命令（ 命令类型 = 0×0202）
    @JvmStatic
    fun syncLightingInfo(entity: LightingInfoEntity): ByteArray {//同步灯光
      val packetData = 0x0202L.toLittleEndian(2) +
              0x0001L.toLittleEndian(2) +
              0x0001L.toLittleEndian(2) +
              0x000AL.toLittleEndian(2) +
              entity.index.toByte() +                    // 序列号 1Byte
              (if (entity.switch) 0x01 else 0x02)+        // 开关 1Byte (开:1, 关:2)
              entity.mode.toByte() +                     // 灯效模式 1Byte (1:常亮；2:呼吸；3:彩虹)
              entity.rgb.toFixByteArrayReverse(3) +      // 色彩值 3Byte (rgb彩色值)
              entity.brightness.toByte() +               // 亮度 1Byte (0-100)
              entity.speed.toByte() +                    // 速速 1Byte (0-10)
              entity.duration.toByte() +                 // 亮灯持续时长 1Byte (1-30)
              //entity.interval.toByte()                 // 亮灯间隔 1Byte (1-60分钟)
              (if (entity.index == 2 || entity.index == 3) 0xFF else entity.interval).toByte()


      stream.write(0x5689L.toLittleEndian(2))
      stream.write(packetData)
      stream.write(ModbusCrc16Utils.calculateModbusCRC16(packetData))
      stream.write(0x3AB5L.toLittleEndian(2))

      val packet = stream.toByteArray().copyOf()
      stream.reset()
      return packet
    }


    //同步灯光免打扰命令（ 命令类型 = 0×0203）
    @JvmStatic
    fun syncLightingNotDisturbInfo(switch: Boolean = false,startHour: Int,startMin: Int,endHour: Int,endMin: Int,): ByteArray {//同步灯光免打扰
      val packetData = 0x0203L.toLittleEndian(2) +
              0x0001L.toLittleEndian(2) +
              0x0001L.toLittleEndian(2) +
              0x0005L.toLittleEndian(2) +
              (if (switch) 0x01 else 0x02) +        // 免打扰开关 1Byte (开:1, 关:2)
              startHour.toByte() +                  // 开始时间-时 1Byte (0-23)
              startMin.toByte() +                   // 开始时间-分 1Byte (0-59)
              endHour.toByte() +                    // 结束时间-时 1Byte (0-23)
              endMin.toByte()                       // 结束时间-分 1Byte (0-59)
      stream.write(0x5689L.toLittleEndian(2))
      stream.write(packetData)
      stream.write(ModbusCrc16Utils.calculateModbusCRC16(packetData))
      stream.write(0x3AB5L.toLittleEndian(2))

      val packet = stream.toByteArray().copyOf()
      stream.reset()
      return packet
    }

    //同步⽤户信息命令（ 命令类型 = 0×0205）
    @JvmStatic
    fun pushUserInfo(height: Int, weight: Int, sex: Boolean, birthday: Long): ByteArray {
      val packetData = 0x0205L.toLittleEndian(2) +
              0x0001L.toLittleEndian(2) +
              0x0001L.toLittleEndian(2) +
              0x00A1L.toLittleEndian(2) +
              height.toLong().toByteArrayReverse() +
              weight.toLong().toByteArrayReverse() +
              (if (sex) 1 else 0).toByte() +
              birthday.toByteArrayReverse()

      stream.write(0x5689L.toLittleEndian(2))
      stream.write(packetData)
      stream.write(ModbusCrc16Utils.calculateModbusCRC16(packetData))
      stream.write(0x3AB5L.toLittleEndian(2))

      val packet = stream.toByteArray().copyOf()
      stream.reset()
      return packet
    }

    //同步(开始)运动信息命令（ 命令类型 = 0×0206）
    @JvmStatic
    fun pushSportInfo(sportType: Int, sportStatus: Int, time: Long): ByteArray {
      val packetData = 0x0206L.toLittleEndian(2) +
              0x0001L.toLittleEndian(2) +
              0x0001L.toLittleEndian(2) +
              0x0008L.toLittleEndian(2) +
              sportType.toByte() +
              sportStatus.toByte() +
              time.toLittleEndian(6)

      stream.write(0x5689L.toLittleEndian(2))
      stream.write(packetData)
      stream.write(ModbusCrc16Utils.calculateModbusCRC16(packetData))
      stream.write(0x3AB5L.toLittleEndian(2))
      val packet = stream.toByteArray().copyOf()
      stream.reset()
      return packet
    }

    //同步界⾯命令（ 命令类型 = 0×0207）
    @JvmStatic
    fun pushAppRunningStatus(isInForeground: Boolean): ByteArray {
      val packetData = 0x0207L.toLittleEndian(2) +
              0x0001L.toLittleEndian(2) +
              0x0001L.toLittleEndian(2) +
              0x0004L.toLittleEndian(2) +
              (if (isInForeground) 0x00000001 else 0xFFFFFFFF).toByteArrayReverse()

      stream.write(0x5689L.toLittleEndian(2))
      stream.write(packetData)
      stream.write(ModbusCrc16Utils.calculateModbusCRC16(packetData))
      stream.write(0x3AB5L.toLittleEndian(2))
      val packet = stream.toByteArray().copyOf()
      stream.reset()
      return packet
    }

    //重启或恢复出⼚控制命令（ 命令类型 = 0×0204）
    @JvmStatic
    fun reboot(): ByteArray {
      val packetData = 0x0204L.toLittleEndian(2) +
              0x0001L.toLittleEndian(2) +
              0x0001L.toLittleEndian(2) +
              0x0001L.toLittleEndian(2) +
              0x01
      stream.write(0x5689L.toLittleEndian(2))
      stream.write(packetData)
      stream.write(ModbusCrc16Utils.calculateModbusCRC16(packetData))
      stream.write(0x3AB5L.toLittleEndian(2))
      val packet = stream.toByteArray().copyOf()
      stream.reset()
      return packet
    }

    @JvmStatic
    fun factoryReset(): ByteArray {
      val packetData = 0x0204L.toLittleEndian(2) +
              0x0001L.toLittleEndian(2) +
              0x0001L.toLittleEndian(2) +
              0x0001L.toLittleEndian(2) +
              0x02
      stream.write(0x5689L.toLittleEndian(2))
      stream.write(packetData)
      stream.write(ModbusCrc16Utils.calculateModbusCRC16(packetData))
      stream.write(0x3AB5L.toLittleEndian(2))
      val packet = stream.toByteArray().copyOf()
      stream.reset()
      return packet
    }

    //上报运动信息命令（ 命令类型 = 0×0301）
    @JvmStatic
    fun appConfirm(): ByteArray {
      val packetData = 0x0301L.toLittleEndian(2) +
              0x0001L.toLittleEndian(2) +
              0x0001L.toLittleEndian(2) +
              0x0001L.toLittleEndian(2) +
              0x01
      stream.write(0x5689L.toLittleEndian(2))
      stream.write(packetData)
      stream.write(ModbusCrc16Utils.calculateModbusCRC16(packetData))
      stream.write(0x3AB5L.toLittleEndian(2))
      val packet = stream.toByteArray().copyOf()
      stream.reset()
      return packet
    }

    //上报实时信息状态命令(命令类型 = 0×0302)
    @JvmStatic
    fun appConfirmRealTimeStatus(): ByteArray {
      val packetData = 0x0302L.toLittleEndian(2) +
              0x0001L.toLittleEndian(2) +
              0x0001L.toLittleEndian(2) +
              0x0001L.toLittleEndian(2) +
              0x01
      stream.write(0x5689L.toLittleEndian(2))
      stream.write(packetData)
      stream.write(ModbusCrc16Utils.calculateModbusCRC16(packetData))
      stream.write(0x3AB5L.toLittleEndian(2))
      val packet = stream.toByteArray().copyOf()
      stream.reset()
      return packet
    }

    //上报实时运动信息命令(命令类型 = 0×0303)
    @JvmStatic
    fun confirmRealTimeSportReport(): ByteArray {
      val packetData = 0x0303L.toLittleEndian(2) +
              0x0001L.toLittleEndian(2) +
              0x0001L.toLittleEndian(2) +
              0x0001L.toLittleEndian(2) +
              0x01
      stream.write(0x5689L.toLittleEndian(2))
      stream.write(packetData)
      stream.write(ModbusCrc16Utils.calculateModbusCRC16(packetData))
      stream.write(0x3AB5L.toLittleEndian(2))
      val packet = stream.toByteArray().copyOf()
      stream.reset()
      return packet
    }

    //上报实时健康信息命令(命令类型 = 0×0304)
    @JvmStatic
    fun confirmRealTimeHealthReport(): ByteArray {
      val packetData = 0x0304L.toLittleEndian(2) +
              0x0001L.toLittleEndian(2) +
              0x0001L.toLittleEndian(2) +
              0x0001L.toLittleEndian(2) +
              0x01
      stream.write(0x5689L.toLittleEndian(2))
      stream.write(packetData)
      stream.write(ModbusCrc16Utils.calculateModbusCRC16(packetData))
      stream.write(0x3AB5L.toLittleEndian(2))
      val packet = stream.toByteArray().copyOf()
      stream.reset()
      return packet
    }

    //主动上报电池状态变更命令(命令类型 = 0×0305)
    @JvmStatic
    fun confirmBatteryStatusReport():  ByteArray {
      val packetData = 0x0305L.toLittleEndian(2) +
              0x0001L.toLittleEndian(2) +
              0x0001L.toLittleEndian(2) +
              0x0001L.toLittleEndian(2) +
              0x01
      stream.write(0x5689L.toLittleEndian(2))
      stream.write(packetData)
      stream.write(ModbusCrc16Utils.calculateModbusCRC16(packetData))
      stream.write(0x3AB5L.toLittleEndian(2))
      val packet = stream.toByteArray().copyOf()
      stream.reset()
      return packet
    }

    //ota升级请求应答（上⾏主动上报,命令类型 = 0×0401）
    @JvmStatic
    fun otaUpgradeRequestResponse(): ByteArray {
      val packetData = 0x0401L.toLittleEndian(2) +
              0x0001L.toLittleEndian(2) +
              0x0001L.toLittleEndian(2) +
              0x0001L.toLittleEndian(2) +
              0x01
      stream.write(0x5689L.toLittleEndian(2))
      stream.write(packetData)
      stream.write(ModbusCrc16Utils.calculateModbusCRC16(packetData))
      stream.write(0x3AB5L.toLittleEndian(2))
      val packet = stream.toByteArray().copyOf()
      stream.reset()
      return packet
    }

    //ota升级请求 (命令类型 = 0×0402）
    @JvmStatic
    fun otaUpgradeRequest(version: Int, fileSize: Long): ByteArray {
      val packetData = 0x0402L.toLittleEndian(2) +
              0x0001L.toLittleEndian(2) +
              0x0001L.toLittleEndian(2) +
              0x0006L.toLittleEndian(2) +
              version.toLong().toLittleEndian(2) +
              fileSize.toLittleEndian(4)
      stream.write(0x5689L.toLittleEndian(2))
      stream.write(packetData)
      stream.write(ModbusCrc16Utils.calculateModbusCRC16(packetData))
      stream.write(0x3AB5L.toLittleEndian(2))
      val packet = stream.toByteArray().copyOf()
      stream.reset()
      return packet
    }

    //ota升级发送数据 (命令类型 = 0×0403）
    @JvmStatic
    fun otaUpgradeSendData(responseCode: Int): ByteArray {
      val packetData = 0x0403L.toLittleEndian(2) +
              0x0001L.toLittleEndian(2) +
              0x0001L.toLittleEndian(2) +
              0x0001L.toLittleEndian(2) +
              responseCode.toByte()
      stream.write(0x5689L.toLittleEndian(2))
      stream.write(packetData)
      stream.write(ModbusCrc16Utils.calculateModbusCRC16(packetData))
      stream.write(0x3AB5L.toLittleEndian(2))
      val packet = stream.toByteArray().copyOf()
      stream.reset()
      return packet
    }

    //单个分包
    @JvmStatic
    fun sendOtaDataPacket(
      totalPacketCount: Int,
      currentPacketIndex: Int,
      firmwareLength: Long,
      chunkData: ByteArray
    ): ByteArray {
      val dataField = firmwareLength.toLittleEndian(4) + chunkData
      val packetData = 0x0403L.toLittleEndian(2) +                    //命令类型
              totalPacketCount.toLong().toLittleEndian(2) +           //总包数
              currentPacketIndex.toLong().toLittleEndian(2) +         //当前包序号
              dataField.size.toLong().toLittleEndian(2) +             //数据长度
              dataField                                                    //数据
      //完整封装
      stream.write(0x5689L.toLittleEndian(2))                    //命令头
      stream.write(packetData)
      stream.write(ModbusCrc16Utils.calculateModbusCRC16(packetData))     //CRC校验
      stream.write(0x3AB5L.toLittleEndian(2))                       //命令尾
      val packet = stream.toByteArray().copyOf()
      stream.reset()
      return packet
    }


  }
}